﻿/**
 * Foxit Software Inc.
 * Copyright(C) 2005-2014, all rights reserved.
 * The following code is copyrighted and contains proprietary information
 * and trade secrets of Foxit Software Inc.

 * Description: Mark up annotation
 * Author: shaojie zhuo
 */
define(function (require, exports, module) {
    var PDFAnnot = require('./Annot.js');
    require('../Interface.js');
    var Interface = WebPDF.Interface;
    var AnnotDataJSONFormat = WebPDF.PDFData.AnnotDataJSONFormat;
    WebPDF.PDFData.MKA_POPUPWIDTH = 180;
    WebPDF.PDFData.MKA_POPUPHEIGHT = 120;

    /**
     * Popup annotation
     * @param jsonData annotation data in JSON format
     * @extends WebPDF.PDFData.PDFAnnot
     * @constructor
     */
    var PDFPopupAnnot = function (jsonData) {
        PDFPopupAnnot.superclass.constructor.call(this, jsonData);
        $.extend(this, {
            /**
             * Get open state of current popup annotation
             * @returns {Number} 0 indicates that current annotation is hidden while 1 indicates that current annotation is visible.
             */
            getOpenState: function () {
                return this.annotJSONData[AnnotDataJSONFormat.openState];
            },
            /**
             * Set open state of current popup annotation
             * @param {Number} openState 0 or 1 is valid
             */
            setOpenState: function (openState) {
                this.annotJSONData[AnnotDataJSONFormat.openState] = openState;
            }
        });
    };
    Interface.extend(PDFPopupAnnot, PDFAnnot);

    WebPDF.PDFData.PDFPopupAnnot = PDFPopupAnnot;

    /**
     * State of markup annotation.
     * @param jsonData state data in JSON format
     * @constructor
     */
    var PDFAnnotState = function (jsonData) {
        this.annotStateJSONData = jsonData;
    };
    PDFAnnotState.prototype = {
        getState: function () {
            return this.annotStateJSONData[AnnotDataJSONFormat.state];
        },
        getStateMode: function () {
            return this.annotStateJSONData[AnnotDataJSONFormat.stateModel];
        }
    };
    WebPDF.PDFData.PDFAnnotState = PDFAnnotState;

    /**
     * Markup annotation
     * @param jsonData annotation data in JSON format
     * @extends WebPDF.PDFData.PDFAnnot
     * @constructor
     */
    var PDFMarkupAnnot = function (jsonData) {
        PDFMarkupAnnot.superclass.constructor.call(this, jsonData);
        this.popup = null;
        this.replyChain = null;
        this.stateList = null;
        /**
         * Group annotations, just reference to other annotation.
         * @type {{String : WebPDF.PDFData.PDFAnnot}}
         */
        this.groupAnnots = {};
        /**
         * Head annotation in groups.
         * @type {WebPDF.PDFData.PDFAnnot | null}
         */
        this.headAnnot = null;
        /**
         * Map for reply annotations, just reference to other annotation.
         * @type {{String : WebPDF.PDFData.PDFAnnot}}
         */
        this.replyChainAnnotMap = {};

        $.extend(this, {
            /**
             * Get opacity of current annotation.
             * @returns {Number} 0 to 1 is valid.
             */
            getOpacity: function () {
                return this.annotJSONData[AnnotDataJSONFormat.opacity];
            },
            /**
             * Get subject of current annotation.
             * @returns {String}
             */
            getSubject: function () {
                if (typeof this.annotJSONData[AnnotDataJSONFormat.subject] == 'undefined')
                    return "";
                return this.annotJSONData[AnnotDataJSONFormat.subject];
            },
            /**
             * Get title of current annotation.
             * @returns {String}
             */
            getTitle: function () {
                return this.annotJSONData[AnnotDataJSONFormat.title];
            },
            /**
             * Get popup annotation according to current annotation.
             * @returns {WebPDF.PDFData.PDFPopupAnnot | null}
             */
            getPopup: function () {
                if (this.popup == null) {
                    if (this.annotJSONData[AnnotDataJSONFormat.popup] == null)
                        return null;
                    this.popup = new PDFPopupAnnot(this.annotJSONData[AnnotDataJSONFormat.popup]);
                }
                return this.popup;
            },
            /**
             * Set popup data of current annotation
             * @param {JSON} jsonPopupData
             */
            setPopupData: function (jsonPopupData) {
                this.annotJSONData[AnnotDataJSONFormat.popup] = jsonPopupData;
            },
            /**
             * Get subtype of current annotation.
             * @returns {String}
             */
            getSubType: function () {
                return this.annotJSONData[AnnotDataJSONFormat.subType];
            },
            /**
             * Get name of text annotation.
             * @returns {String}
             */
            getTextAnnotName: function () {
                return this.annotJSONData[AnnotDataJSONFormat.textAnnotName];
            },
            /**
             * Initialize reply chain for current annotation.
             * @private
             */
            _initReplyChain: function () {
                if (this.replyChain == null) {
                    this.replyChain = [];
                    if (this.annotJSONData[AnnotDataJSONFormat.replyChain] == null) {
                        return;
                    }
                    var replyCnt = this.annotJSONData[AnnotDataJSONFormat.replyChain].length;
                    for (var i = 0; i < replyCnt; i++) {
                        var annot = new PDFMarkupAnnot(this.annotJSONData[AnnotDataJSONFormat.replyChain][i]);
                        var newAnnotName = WebPDF.Common.createUniqueId();
                        annot.setAnnotName(newAnnotName);
                        this.replyChain[i] = annot;
                        this.replyChainAnnotMap[newAnnotName] = annot;
                        this.replyChain[i]._initReplyChain();
                    }
                }
            },
            /**
             * Get reply annot by name.
             * @param {String} annotName name of annotation
             * @returns {WebPDF.PDFData.PDFAnnot | null}
             */
            getReplyAnnotByName: function (annotName) {
                return this.replyChainAnnotMap[annotName];
            },
            /**
             * Get reply chain of current annotation.
             * @returns {null|Array.<WebPDF.PDFData.PDFAnnot>}
             */
            getReplyChain: function () {
                this._initReplyChain();
                return this.replyChain;
            },
            /**
             * Initialize state list of current annotation.
             * @private
             */
            _initStateList: function(){
                if (this.stateList == null) {
                    this.stateList = [];
                    if (this.annotJSONData[AnnotDataJSONFormat.stateList] == null) {
                        return;
                    }
                    var stateCnt = this.annotJSONData[AnnotDataJSONFormat.stateList].length;
                    for (var i = 0; i < stateCnt; i++) {
                        this.stateList[i] = new PDFAnnotState(this.annotJSONData[AnnotDataJSONFormat.stateList][i]);
                    }
                }
            },
            /**
             * Get state list of current annotation.
             * @returns {null|Array.<WebPDF.PDFData.PDFAnnotState>}
             */
            getStateList:function () {
                this._initStateList();
                return this.stateList;
            },
            /**
             * Get map of group annotations.
             * @returns {{String: WebPDF.PDFData.PDFAnnot}}
             */
            getGroupAnnotMap: function () {
                return this.groupAnnots;
            },
            /**
             * Add annotation to group
             * @param {WebPDF.PDFData.PDFAnnot} annot annotation to add.
             * @returns {boolean} return true if adding successfully, otherwise return false.
             */
            addAnnotToGroup: function(annot) {
                if (annot == null)
                    return false;
                this.groupAnnots[annot.getAnnotName()] = annot;
                return true;
            },
            /**
             * Get head annotation of groups.
             * @returns {WebPDF.PDFData.PDFAnnot|null}
             */
            getHeadAnnot: function(){
                return this.headAnnot;
            },
            /**
             * Set head annotation of current groups.
             * @param {WebPDF.PDFData.PDFAnnot} headAnnot
             */
            setHeadAnnot: function(headAnnot){
                this.headAnnot = headAnnot;
            },
            /**
             * Get ancestor annotation of current head annotation
             * @returns {WebPDF.PDFData.PDFAnnot|null}
             */
            getHeadAncestorAnnot: function(){
                var headAnnot = this.headAnnot;
                while (headAnnot) {
                    if (headAnnot.getType() === WebPDF.Data.AnnotType.MarkUp) {
                        if (headAnnot.getHeadAnnot())
                            headAnnot = headAnnot.getHeadAnnot();
                        else
                            return headAnnot;
                    }
                    else
                        return headAnnot;
                }
                return headAnnot;
            }
        });
    };
    Interface.extend(PDFMarkupAnnot, PDFAnnot);

    WebPDF.PDFData.PDFMarkupAnnot = PDFMarkupAnnot;
    return WebPDF.PDFData.PDFMarkupAnnot;
});